package com.xctech.yace.main;


import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.xctech.yace.factory.MybatisSessionFactory;
import com.xctech.yace.mapper.DbCompareMapper;
import com.xctech.yace.pojo.DbCompareRes;
import com.xctech.yace.pojo.UserTabCols;
import com.xctech.yace.util.DirUtil;
import com.xctech.yace.util.ExcelUtil;
import org.apache.ibatis.session.SqlSessionFactory;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;

public class DbCompare {

    /**
     * 比较oracle不同库中相同表结构版本变化
     * 比较user_tab_cols.table_name
     * 1.新增字段 column_name
     * 2.字段类型变化 data_type,data_length(列的数据类型的字节长度),data_precision(数字类型的实际长度),data_scale(小数点位数)
     */
    public static boolean dbCompare(Properties params, Map<String,String> tables, String path) throws Exception {

        SqlSessionFactory originFactory = MybatisSessionFactory.getOriginFactory(params);
        SqlSessionFactory targetFactory = MybatisSessionFactory.getTargetFactory(params);
        List<DbCompareRes> list = Lists.newArrayList();

        for (String tableName : tables.keySet()) {
            List<UserTabCols> origin = originFactory.openSession().getMapper(DbCompareMapper.class).selectUserTabCols(tableName.toUpperCase());
            List<String> originCols = origin.stream().map(UserTabCols::getColumnName).collect(Collectors.toList());
            List<UserTabCols> target = targetFactory.openSession().getMapper(DbCompareMapper.class).selectUserTabCols(tables.get(tableName).toUpperCase());
            List<String> targetCols = target.stream().map(UserTabCols::getColumnName).collect(Collectors.toList());
            for (String col : targetCols) {
                if (!originCols.contains(col)) {//新增
                    UserTabCols userTabCols = target.stream().filter(obj -> obj.getColumnName().equals(col)).findFirst().orElse(null);
                    if (userTabCols != null) {
                        if (userTabCols.getDataType().equals("NUMBER")) {
                            String newType = "NUMBER(" + userTabCols.getDataPrecision() + "," + userTabCols.getDataScale() + ")";
                            list.add(new DbCompareRes(userTabCols.getTableName(), userTabCols.getColumnName(), null, newType));
                        } else {
                            list.add(new DbCompareRes(userTabCols.getTableName(), userTabCols.getColumnName(), null, userTabCols.getDataType()));
                        }
                    }
                } else {//修改
                    UserTabCols tabOri = origin.stream().filter(obj -> obj.getColumnName().equals(col)).findFirst().orElse(null);
                    UserTabCols tabTar = target.stream().filter(obj -> obj.getColumnName().equals(col)).findFirst().orElse(null);
                    if (tabOri != null && tabTar != null) {
                        if (!tabOri.getDataType().equals(tabTar.getDataType()) ||
                                (tabOri.getDataLength() != null && tabTar.getDataLength() != null && !tabOri.getDataLength().equals(tabTar.getDataLength())) ||
                                (tabOri.getDataPrecision() != null && tabTar.getDataPrecision() != null && !tabOri.getDataPrecision().equals(tabTar.getDataPrecision())) ||
                                (tabOri.getDataScale() != null && tabTar.getDataScale() != null && !tabOri.getDataScale().equals(tabTar.getDataScale()))) {
                            String oriType = tabOri.getDataPrecision() == null ? tabOri.getDataType() + "(" + tabOri.getDataLength() + ")" : tabOri.getDataType() + "(" + tabOri.getDataPrecision() + "," + tabOri.getDataScale() + ")";
                            String newType = tabTar.getDataPrecision() == null ? tabTar.getDataType() + "(" + tabTar.getDataLength() + ")" : tabTar.getDataType() + "(" + tabTar.getDataPrecision() + "," + tabTar.getDataScale() + ")";
                            list.add(new DbCompareRes(tabOri.getTableName(), col, oriType, newType));
                        }
                    }

                }
            }
            for (String col : originCols) {//删除
                if (!targetCols.contains(col)) {
                    UserTabCols userTabCols = origin.stream().filter(obj -> obj.getColumnName().equals(col)).findFirst().orElse(null);
                    if (userTabCols != null) {
                        if (userTabCols.getDataType().equals("NUMBER")) {
                            String oriType = "NUMBER(" + userTabCols.getDataPrecision() + "," + userTabCols.getDataScale() + ")";
                            list.add(new DbCompareRes(userTabCols.getTableName(), userTabCols.getColumnName(), oriType, null));
                        } else {
                            list.add(new DbCompareRes(userTabCols.getTableName(), userTabCols.getColumnName(), userTabCols.getDataType(), null));
                        }
                    }
                }
            }

        }
        String[] title = {"表名", "字段名", "原类型", "新类型"};
        ExcelUtil.writeDbRes(title, path, list);
//        EasyExcel.write(fileRes, DbCompareRes.class).sheet().doWrite(list);
        return true;
    }

//    public static void main(String[] args) throws Exception {
//        dbCompare();
//    }

}
